<?php

namespace App\Http\Controllers;

use App\Models\Coin;
use App\Models\User;
use App\Models\UserInvite;
use App\Models\UserNode;
use App\Models\UserNodeLog;
use App\Models\UserOrder;
use App\Models\UserOrderLog;
use App\Models\Wallet;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;

class PublicController extends Controller
{
    // 获取节点价格
    private function node_price()
    {
        return 500;
    }
    // 获取节点价格
    private function isEn()
    {
        return UserNode::getLang() == 'en';
    }
    
    protected function json_ok($data = null)
    {
        return response()->json([
            'code' => 200,
            'message' => 'ok',
            'data' => $data
        ]);
    }
    protected function json_err($message = null, $code = 400, $data = null)
    {
        return response()->json([
            'code' => $code,
            'message' => $message,
            'data' => $data
        ]);
    }

    protected function get_user_id()
    {

        // return 298061881;
        // return 298061825;

        $token = request()->bearerToken();
        if (!$token) {
            $token = request()->input('token');
        }

        if(!$token){
            $token = request()->header('token');
        }

        if (!$token) {
            return 0;
        }
        $user_id = $this->get_user_id_by_token($token);
        Log::info('token: ' . $token . ' user_id: ' . $user_id);
        return (int) $user_id;
    }

    // 全网算力
    public function computility()
    {
        $user_id = $this->get_user_id();
        // 当日产币
        $today_mint_num = UserNode::getUserDailyMintNum($user_id);
        // 总产币
        $total_mint_num = UserNode::getUserTotalMintNum($user_id);
        // 我的算力
        $my_computility = UserNode::getUserNodePower($user_id);
        // 全网算力
        $total_computility = UserNode::getAllNodePower();
        // 拥有的节点数
        $my_node_num = UserNode::getBuyNodeNum($user_id);
        $data = [
            'today_mint_num' => $today_mint_num,
            'total_mint_num' => $total_mint_num,
            'my_computility' => $my_computility,
            'total_computility' => $total_computility,
            'my_node_num' => $my_node_num,
            'node_price' => $this->node_price(),
            'max_node_num' => UserNode::getMaxBuyNodeNum(),
        ];
        return $this->json_ok($data);
    }

    // 节点列表
    public function node_list()
    {
        $user_id = $this->get_user_id();
        $nodes = UserNode::query()->where('user_id', $user_id)->orderBy('id', 'asc')->paginate(10);
        return $this->json_ok($nodes);
    }
    // 节点记录列表
    public function node_log_list()
    {
        $user_id = $this->get_user_id();
        $node_id = (int)request()->input('node_id');
        $nodes = UserNodeLog::where('user_id', $user_id)->where('node_id', $node_id)->orderBy('id', 'desc')->paginate(10);
        return $this->json_ok($nodes);
    }

    // 购买节点
    public function buy_node()
    {
        $user_id = $this->get_user_id();
        if (empty($user_id)) {
            return $this->json_err($this->isEn() ? 'Please login first' : '请先登录', 401);
        }

        $buy_num = (int) request()->input('buy_num');
        $can_buy_num = UserNode::getCanBuyNodeNum($user_id);

        if ($buy_num <= 0) {
            return $this->json_err($this->isEn() ? 'Please select purchase quantity' : '请选择购买数量');
        }

        if ($can_buy_num < $buy_num) {
            if($this->isEn()){
                return $this->json_err(sprintf("Maximum purchase limit: %s nodes", $can_buy_num));
            }
            return $this->json_err('最多可购买' . $can_buy_num . '个节点');
        }

        DB::beginTransaction();
        try {
            // 单价
            $price = $this->node_price();
            // 总金额
            $total_money = round($price * $buy_num, 2);
            if(!Wallet::reduceUsdt($user_id, $total_money)){
                throw new \Exception($this->isEn() ? 'Payment failed' :'扣款失败');
            }

            if (!UserNode::buyNode($user_id, $buy_num)) {
                throw new \Exception($this->isEn() ? 'Purchase failed' :'购买失败');
            }
            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->json_err($e->getMessage());
        }
        return $this->json_ok();
    }


    // 根据token获取用户id
    public function get_user_id_by_token($token)
    {
        $api = 'http://api.columbus.work/api/api/user/getInfo';
        $header = [
            'token' => $token,
            'Content-Type' => 'application/json',
            'language' => 'cn'
        ];

        $client = new \GuzzleHttp\Client();
        try {
            $response = $client->request('GET', $api, [
                'headers' => $header,
            ]);
            $data = json_decode($response->getBody(), true);
            if ($data['code'] != 200) {
                return 0;
            }
            return $data['data']['id'] ?? 0;
        } catch (\Exception $e) {
            return 0;
        }
    }

    // 套餐数据
    public function get_service($id = 0){
        $nodes = [
            ['id' =>101,'name' => '7天',   'days' => 7,    'num' => 1000, 'release_times'=>1, 'profit'=>'60'],
            ['id' =>102,'name' => '28天',  'days' => 28,   'num' => 1000, 'release_times'=>4, 'profit'=>'70'],
            ['id' =>103,'name' => '63天',  'days' => 63,   'num' => 1000, 'release_times'=>9, 'profit'=>'80'],
            ['id' =>104,'name' => '140天', 'days' => 140,  'num' => 1000, 'release_times'=>20, 'profit'=>'90'],
            ['id' =>105,'name' => '180天', 'days' => 280,  'num' => 1000, 'release_times'=>40, 'profit'=>'100'],
        ];
        if($id){
            $nodes = array_filter($nodes, function ($item) use ($id) {
                return $item['id'] == $id;
            });
            if(empty($nodes)){
                return [];
            }

            return $nodes[0];
        }
        return $nodes;
    }

    // 套餐列表
    public function service_list()
    {
        $nodes = $this->get_service();
        return $this->json_ok($nodes);
    }
    // 套餐信息
    public function service_info()
    {
        $id = (int)request()->input('id');
        $nodes = $this->get_service($id);
        return $this->json_ok($nodes);
    }

    
    //创建订单
    public function add_order()
    {
        $user_id = $this->get_user_id();
        $id = (int) request()->input('id');

        $service = $this->get_service($id);
        if(empty($service)){
            return $this->json_err($this->isEn() ? 'Please select a service' :'请选择服务');
        }

        DB::beginTransaction();
        try {

            $buy_num = floatval($service['num']);
            // 单价
            $price = Coin::getCoinPrice(2);
            // 总金额
            $total_money = round($buy_num / $price, 2);
            if(!Wallet::reduceUsdt($user_id, $total_money,2,1)){
                throw new \Exception($this->isEn() ? 'Payment failed' :'扣款失败');
            }

            if (!UserOrder::buyNode($user_id, $buy_num,$total_money,$price, $service)) {
                throw new \Exception($this->isEn() ? 'Purchase failed' :'购买失败');
            }
            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->json_err($e->getMessage());
        }
        
        return $this->json_ok();
    }
    //订单列表
    public function order_list()
    {
        $user_id = $this->get_user_id();
        $nodes = UserOrder::where('user_id', $user_id)->orderBy('id', 'desc')
        ->select("num","create_time","days","coin_name")
        ->paginate(10);

        foreach ($nodes->items() as $item){
            if($this->isEn()){
                $item->days = (int)$item->days . 'days';
            }else{
                $item->days = (int)$item->days . '天';
            }
            $item->num = round($item->num, 2);

         }

        return $this->json_ok($nodes);
    }
    //收益列表
    public function order_log()
    {
        $user_id = $this->get_user_id();
        $nodes = UserOrderLog::where('user_id', $user_id)->orderBy('id', 'desc')
        ->select("type","create_time","num","coin_name")
        ->paginate(10);

        // 类型:1周分 2返佣
        $typemap = [
            1 => $this->isEn() ? 'Weekly dividend' :'周分',
            2 => $this->isEn() ? 'Commission' :'返佣'
        ];

        foreach ($nodes->items() as $item){
            $item->num = round($item->num, 2);
            $item->type_text = $typemap[$item->type] ?? '';
        }

        return $this->json_ok($nodes);
    }
    //直推用户列表
    public function reuser_list()
    {
        $user_id = $this->get_user_id();
        $nodes = UserInvite::where('up_user_id', $user_id)->orderBy('id', 'desc')
            ->select("id","user_id","create_time","rebate","rebate_status")
        ->paginate(10);

        // rebate 保留2位
        foreach ($nodes->items() as $item){
            $item->rebate = round($item->rebate, 2);
            if($this->isEn()){
                $item->rebate_status_text = $item->rebate_status == 1 ? 'Valid' : 'Invalid';
            }else{
                $item->rebate_status_text = $item->rebate_status == 1 ? '有效' : '无效';
            }
        }

        return $this->json_ok($nodes);
    }
    //修改返佣状态
    public function update_rebate_status()
    {
        $user_id = $this->get_user_id();
        $id = (int) request()->input('id');
        $rebate_status = (int) request()->input('rebate_status');
        try {
            if(!in_array($rebate_status, [1,2])){
                throw new \Exception($this->isEn() ? 'Invalid status' :'状态无效');
            }

            if($rebate_status == 2){
                $next_user_id = UserInvite::where('id', $id)->value('user_id');
                if(empty($next_user_id)){
                    throw new \Exception($this->isEn() ? 'Invalid user' :'用户无效');
                }
                // 下级是否有订单
                $order_count = UserOrder::where('user_id', $next_user_id)->where('status', 1)->count();
                if($order_count > 0){ 
                    throw new \Exception($this->isEn() ? 'Cannot set to freeze' :'不能设置为冻结');
                }
                $nextids = UserInvite::where('up_user_id', $next_user_id)->pluck('user_id')->toArray();
                if(!empty($nextids)){
                    $next_order_count = UserOrder::whereIn('user_id', $nextids)->where('status', 1)->count();
                    if($next_order_count > 0){ 
                        throw new \Exception($this->isEn() ? 'Cannot set to freeze' :'不能设置为冻结');
                    }
                }
            }

            UserInvite::where('id', $id)->where("up_user_id", $user_id)->update(['rebate_status' => $rebate_status]);
        } catch (\Exception $e) {
            return $this->json_err($e->getMessage());
        }
        return $this->json_ok();
    }
    //修改返佣数量
    public function update_rebate()
    {
        $user_id = $this->get_user_id();
        $id = (int) request()->input('id');
        $rebate = (float) request()->input('rebate');
        try {
            $user_rebate = UserInvite::where('id', $id)->where("up_user_id", $user_id)->first();
            if(!$user_rebate){
                throw new \Exception($this->isEn() ? 'Invalid user' :'用户无效');
            }
            if($rebate < $user_rebate->rebate){
                throw new \Exception($this->isEn() ? 'Invalid rebate' :'只能调高不能调低');
            }
            UserInvite::where('id', $id)->where("up_user_id", $user_id)->update(['rebate' => $rebate]);
        } catch (\Exception $e) {
            return $this->json_err($e->getMessage());
        }
        return $this->json_ok();
    }
    public function invite_bind()
    {
        $user_id = $this->get_user_id();
        $code = request()->input('invite_code');
        try {
            if(!$user_id){
                throw new \Exception($this->isEn() ? 'Invalid user' :'用户无效');
            }
            
            $r = UserInvite::addInvite($user_id,$code);

            if($r == -1){
                throw new \Exception($this->isEn() ? 'Invalid invitation code' :'邀请码无效');
            }elseif($r == -2){
                throw new \Exception($this->isEn() ? 'Cannot bind yourself' :'不能绑定自己');
            }elseif($r == -3){
                throw new \Exception($this->isEn() ? 'Already bound, cannot bind again' :'已绑定，不能重复绑定');
            }

        } catch (\Exception $e) {
            return $this->json_err($e->getMessage());
        }
        return $this->json_ok();
    }
    public function coin_price()
    {
        return $this->json_ok([
            'coin_price' => floatval(Coin::getCoinPrice(2)),
        ]);
    }
    public function invite_status()
    {
        $user_id = $this->get_user_id();
        $status = UserInvite::where('user_id', $user_id)->first();
        return $this->json_ok([
            'status' => $status ? 1 : 0
        ]);
    }

}
